﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
 * As classes Token e Tokens são as classes pai para todos os items simbólicos
 * na sintaxe do montador
 * 
 * Tokens são identificados pelo um string, único dentro da coleção.
 * Em classes derivadas, tokens são vinculados com demais informações.
 * 
 */

namespace Sintaxe.Tokens
{
    public class Tokens
    {
        public List<IToken> Itens = new List<IToken>();  // Não funciona List<Token> pq. classes derivados não são aceitas


        public IEnumerable<string> Lexemas()
        {
            // As IDs de todos os tokens daqui
            foreach (IToken ii in Itens) yield return ii.ID();
        }

        public Token Item(string prmID)
        {
            return (Token) Itens.Find(x=> x.ID() == prmID);
        }

        public bool Existe(string prmID)
        {
            return Itens.Exists(x => x.ID() == prmID);
        }
    }

    public class Token : IToken
    {
        readonly string _ID;

        public Token(string prmId)
        {
            if (prmId == null) throw new ArgumentNullException("Não pode criar token com ID == null.");
            if (prmId == "") throw new ArgumentOutOfRangeException("Não pode criar Token com string vazio.");
            _ID = prmId;
        }

        public string ID()
        {
            return _ID;
        }

        public static bool LegitId(string id)
        {
            // testar se id é um identificador válido
            if (id == null) return false;
            if (id == "") return false;
            if (!Char.IsLetter(id[0])) return false;
            for (int ii = 1; ii < id.Length; ii++) if (!Char.IsLetterOrDigit(id[ii])) return false; 
            return true;
        }
    }

    public interface IToken
    {
        string ID();
    }
}
